﻿package  
{
	import com.janisRadins.asDraw.Curve;
	import com.janisRadins.asDraw.DrawUtils;
	import com.robertpenner.bezier.CubicCurve;
	import flash.display.GraphicsPath;
	import flash.display.Sprite;
	import flash.geom.Point;
	import mx.utils.ObjectUtil;
	
	/**
	 * ...
	 * @author Jānis Radiņš
	 */
	public class T2 extends Sprite {
		private var p1:Point = new Point(150, 100);
		private var p2:Point = new Point(20, 10);
		private var p3:Point = new Point(150, 30);
		private var p4:Point = new Point(110, 300);
		public function T2() {
			for (var i:uint = 1; i <= 4; i++) {
				this["p" + i].x *= 2;
				this["p" + i].y *= 2;
			}
			
			drawCubic();
			//drawQuadratic();
			drawPoints()
			//drawCurves()
			drawCubicCurve();
		}
		
		private function drawPoints():void {
			for (var i:uint = 1; i <= 4; i++) {
				graphics.beginFill(0x123456, 0.5);
				graphics.drawCircle(this["p" + i].x, this["p" + i].y, 3);
				graphics.endFill();
			}
		}
		
		private function getPointOnCubitBezzier(t:Number, p0:Number, p1:Number, p2:Number, p3:Number):Number {
			return Math.pow(1 - t, 3) * p0 + 3 * Math.pow(1 - t, 2) * t * p1 + 3 * (1 - t) * Math.pow(t, 2) * p2 + Math.pow(t, 3) * p3;
		}
		
		private function drawCubic():void {
			graphics.lineStyle(1, 0xFF0000, 0.5);
			graphics.moveTo(p1.x, p1.y);
			for (var t:Number = 0; t <= 1; t += 0.01) {
				graphics.lineTo(
					getPointOnCubitBezzier(t, p1.x, p2.x, p3.x, p4.x),
					getPointOnCubitBezzier(t, p1.y, p2.y, p3.y, p4.y)
				)
			}
		}
		
		private function drawQuadratic():void {
			var midP:Point = new Point(
				getPointOnCubitBezzier(0.5, p1.x, p2.x, p3.x, p4.x),
				getPointOnCubitBezzier(0.5, p1.y, p2.y, p3.y, p4.y)
			)
			
			graphics.lineStyle(1, 0x00FF00, 0.5);
			graphics.moveTo(p1.x, p1.y);
			graphics.curveTo(p2.x, p2.y, midP.x, midP.y);
			
			graphics.curveTo(p3.x, p3.y, p4.x, p4.y);
		}
		
		private function drawCurves():void {
			var midP:Point = new Point(
				getPointOnCubitBezzier(0.5, p1.x, p2.x, p3.x, p4.x),
				getPointOnCubitBezzier(0.5, p1.y, p2.y, p3.y, p4.y)
			)
			var p025:Point = new Point(
				getPointOnCubitBezzier(0.25, p1.x, p2.x, p3.x, p4.x),
				getPointOnCubitBezzier(0.25, p1.y, p2.y, p3.y, p4.y)
			)
			var c:Curve = new Curve();
			c.anchorX = midP.x-p1.x;
			c.anchorY = midP.y-p1.y;
			c.visualControlX = p025.x-p1.x;
			c.visualControlY =  p025.y - p1.y;
			
			var cmd:GraphicsPath = c.getCurveSegment();
			cmd = DrawUtils.moveGraphicPath(cmd, p1);
			graphics.lineStyle(1, 0x123456, 0.5);
			graphics.moveTo(p1.x, p1.y)
			graphics.drawPath(cmd.commands, cmd.data, cmd.winding);
			
			var p075:Point = new Point(
				getPointOnCubitBezzier(0.75, p1.x, p2.x, p3.x, p4.x),
				getPointOnCubitBezzier(0.75, p1.y, p2.y, p3.y, p4.y)
			)
			
			c.anchorX = p4.x - midP.x;
			c.anchorY = p4.y - midP.y;
			
			c.visualControlX = p075.x - midP.x;
			c.visualControlY =  p075.y - midP.y;
			
			cmd = c.getCurveSegment();
			cmd = DrawUtils.moveGraphicPath(cmd, midP);
			graphics.lineStyle(1, 0x123456, 0.5);
			graphics.moveTo(midP.x, midP.y)
			graphics.drawPath(cmd.commands, cmd.data, cmd.winding);
		}
		private function drawCubicCurve():void {
			graphics.lineStyle(1, 0x654321, 0.5);
			var c:CubicCurve = new CubicCurve(this);
			trace(ObjectUtil.toString(c.drawBezier(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y)));
		}
	}
	
}